package gui.typeEditors;

import java.util.ArrayList;
import java.util.Arrays;

import owg.util.euclidian.V3D;

/**The methods in this class are designed to never throw exceptions, and return a default value if they fail.
 * They may only return null if the default value is null.*/
public class TypeParser
	{
	/**Boolean parser that never throws exceptions*/
	public static Boolean parseBoolean(String value, Boolean defaultValue)
		{
		if(value == null) return defaultValue;
		try	{
			return Boolean.parseBoolean(value);
			}
		catch(Exception e) 
			{
			return defaultValue;
			}
		}
	/**Byte parser that never throws exceptions*/
	public static Byte parseByte(String value, Byte defaultValue)
		{
		if(value == null) return defaultValue;
		try	{
			return Byte.parseByte(value);
			}
		catch(Exception e) 
			{
			return defaultValue;
			}
		}
	/**Short parser that never throws exceptions*/
	public static Short parseShort(String value, Short defaultValue)
		{
		if(value == null) return defaultValue;
		try	{
			return Short.parseShort(value);
			}
		catch(Exception e) 
			{
			return defaultValue;
			}
		}
	/**Integer parser that never throws exceptions*/
	public static Integer parseInteger(String value, Integer defaultValue)
		{
		if(value == null) return defaultValue;
		try	{
			return Integer.parseInt(value);
			}
		catch(Exception e) 
			{
			return defaultValue;
			}
		}
	/**Long parser that never throws exceptions*/
	public static Long parseLong(String value, Long defaultValue)
		{
		if(value == null) return defaultValue;
		try	{
			return Long.parseLong(value);
			}
		catch(Exception e) 
			{
			return defaultValue;
			}
		}
	/**Enum parser. Note that this demands that the type is an Enum type, or it would not make sense to call it.*/
	public static<T extends Enum<T>> Enum<T> parseEnum(Class<T> type, String value, int defaultIndex)
		{
		if(value == null) return type.getEnumConstants()[defaultIndex];
		try 
			{
			return Enum.valueOf(type, value);
			}
		catch (Exception e)
			{
			return type.getEnumConstants()[defaultIndex];
			}
		}
	
	/**Float parser that never throws exceptions*/
	public static Float parseFloat(String value, Float defaultValue)
		{
		if(value == null) return defaultValue;
		try	{
			return Float.parseFloat(value);
			}
		catch(Exception e) 
			{
			return defaultValue;
			}
		}
	
	/**Double parser that never throws exceptions*/
	public static Double parseDouble(String value, Double defaultValue)
		{
		if(value == null) return defaultValue;
		try	{
			return Double.parseDouble(value);
			}
		catch(Exception e) 
			{
			return defaultValue;
			}
		}
	
	/**Somewhat of a curiosity, this method only returns defaultValue if value is null.*/
	public static String parseString(String value, String defaultValue)
		{
		if(value == null)
			return defaultValue;
		else
			return value;
		}
	/**
	 * Float array parser
	 * @param value The string value to be parsed. It must be a sequence of floats separated by single commas.
	 * @param defaultValue The value to return if the parsing fails.
	 * @param minimumNumElements The minimum number of elements in the returned array.
	 * @return defaultValue if one or more of the floats in the value could not be parsed, 
	 * or if the value contains less than minimumNumElements number of floats, the parsed value otherwise.
	 */
	public static float[] parseFloatArray(String value, float[] defaultValue, int minimumNumElements)
		{
		if(value == null) return defaultValue;
		try {
			String[] strings = value.split(",");
			if(strings.length < minimumNumElements)
				return defaultValue;
			float[] returnValue = new float[strings.length];
			for(int i = 0; i < strings.length; i++)
				{
				returnValue[i] = Float.parseFloat(strings[i]);
				}
			return returnValue;
			}
		catch(Exception e)
			{
			return defaultValue;
			}
		}
	
	/**
	 * Double array parser
	 * @param value The string value to be parsed. It must be a sequence of doubles separated by single commas.
	 * @param defaultValue The value to return if the parsing fails.
	 * @param minimumNumElements The minimum number of elements in the returned array.
	 * @return defaultValue if one or more of the doubles in the value could not be parsed, 
	 * or if the value contains less than minimumNumElements number of doubles, the parsed value otherwise.
	 */
	public static double[] parseDoubleArray(String value, double[] defaultValue, int minimumNumElements)
		{
		if(value == null) return defaultValue;
		try {
			String[] strings = value.split(",");
			if(strings.length < minimumNumElements)
				return defaultValue;
			double[] returnValue = new double[strings.length];
			for(int i = 0; i < strings.length; i++)
				{
				returnValue[i] = Double.parseDouble(strings[i]);
				}
			return returnValue;
			}
		catch(Exception e)
			{
			return defaultValue;
			}
		}
	public static V3D parseV3D(String value, V3D defaultValue)
		{
		if(value == null)
			return defaultValue;
		try 
			{
			return V3D.parseV3D(value);
			}
		catch(Exception e)
			{
			return defaultValue;
			}
		}
	/**Parse the input string into an ArrayList of substrings based on the given delimiter regex.
	 * Providing a null delimiter will cause the returned list to contain only one element, 
	 * namely the input string itself. This method will retain all empty substrings.*/
	public static ArrayList<String> parseList(String val, String delimiterRegex)
		{
		ArrayList<String> newValues = new ArrayList<String>();
		if(val != null)
			{
			String[] vals = parseStringArray(val, delimiterRegex);
			newValues.addAll(Arrays.asList(vals));
			}
		return newValues;
		}
	/**Parse the input string into an array of substrings based on the given delimiter regex.
	 * Providing a null delimiter will cause the returned array to contain only one element, 
	 * namely the input string itself. This method will retain all empty substrings.*/
	public static String[] parseStringArray(String val, String delimiterRegex)
		{
		if(val == null)
			return new String[0];
		if(delimiterRegex == null)
			return new String[]{val};
		return val.split(delimiterRegex, -1);
		}
	}
